package com.qingzhuge.web.converter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.qingzhuge.common.jwt.JwtTokenUtil;
import com.qingzhuge.exception.TokenException;
import com.qingzhuge.common.jwt.security.DataSecurityAction;
import com.qingzhuge.autoconfigure.QingTingProperties;
import com.qingzhuge.common.utils.HashUtil;
import com.qingzhuge.common.utils.WebUtil;
import com.qingzhuge.web.security.BaseTransferEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * @author : zero.xiao
 * @description : 带签名的http信息转化器
 * @date :2018/7/4 0004 下午 16:10
 * @since : 1.0.0
 * @modified :
 */
public class WithSignMessageConverter extends FastJsonHttpMessageConverter {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private QingTingProperties properties;

    @Autowired
    private DataSecurityAction dataSecurityAction;

    @Override
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        if (properties.getSecurity().isOpenEncrypt()) {

            InputStream in = inputMessage.getBody();
            Object o = JSON.parseObject(in, super.getFastJsonConfig().getCharset(), BaseTransferEntity.class, super.getFastJsonConfig().getFeatures());

            //先转化成原始的对象
            BaseTransferEntity baseTransferEntity = (BaseTransferEntity) o;

            //校验签名
            String token = Objects.requireNonNull(WebUtil.getRequest()).getHeader(properties.getSecurity().getToken()).substring(7);
            String md5KeyFromToken = JwtTokenUtil.getMd5KeyFromToken(token);

            String object = baseTransferEntity.getData();
            String json = dataSecurityAction.unlock(object);
            String encrypt = HashUtil.md5(object + md5KeyFromToken);

            if (encrypt.equals(baseTransferEntity.getSign())) {
                logger.debug("签名校验成功!");
            } else {
                logger.debug("签名校验失败,数据被改动过!");
                throw new TokenException();
            }
            //校验签名后再转化成应该的对象
            return JSON.parseObject(json, type);
        }else {
            return super.read(type,contextClass,inputMessage);
        }
    }
}